/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once


#include <基本类型.h>
#include <线性代数/变换.h>
#include <list>
#include <set>

#include "引擎枚举数据.h"
#include "引擎数据类型.h"
#include "core/设备内存缓存.h"
#include "底层绘图/底层绘图框架.h"


//using namespace std;


typedef struct {
	vec4	speed;
	float32	密度;
}S_FLIP可视数据;

typedef struct {
	vec4	loc_speed;
}S_PBF可视数据;






struct S_Object {
	uint32		 m_ID;
	uint32  m_globalID;
	std::wstring m_Name;

	static C_Key分配器 m_ID生成器;

	S_Object(uint32 key=0);
	~S_Object();


	virtual S_Object* f_get(uint32 key) { return 0; }
	//static	S_Object*	f_get(uint32 key);
	//virtual	S_Object*	f_get子类对象(uint32 key) = 0;
	/*static S_Object* get(uint32 key) {
		return f_get子类对象(key);
	}*/
};


typedef void(*fun_物体async_p)(S_Object* obj);


/*inline S_Object* _f_get容器中对象(S_键值序列容器<uint32, S_Object*>& 容器, uint32 id_name) {
	if (容器.f_is存在(id_name)) {
		return 容器[id_name];
	}
	return nullptr;
}*/





struct S_物理体 : public S_Object {
	E_物理引擎			m_物理引擎枚举;
	E_物理体类型		m_Type;
	void*				m_Data;
	uint64				m_全局偏移;
	float32				m_密度;
	float32				m_重量;
	S_Tranform			m_变换;

	S_Object*			m_绑定物体;
	std::string			m_XML;
	Mat44f				m_Matrix;

	S_物理体(uint32 key = 0);
	~S_物理体();

	//void				f_绑定user到物理体上(void* data);
	static S_物理体*	f_get(uint32 key);

	virtual void*		f_getBody() { return 0; }
	virtual void*		f_get关联对象() { return 0; }

	virtual void		f_绑定关联对象(void* data) { ; }
	virtual void		f_绑定关联对象(void* data, uint32 id) { ; }
	virtual void		f_冻结(bool no) {}

	virtual void		f_setLocRot(const vec3& l, const vec3& r) {}
	virtual void		f_setPos(const vec3& l) { m_变换.location = l; }
	virtual void		f_setRot(const vec3& r) { m_变换.rotation = r; }
	virtual void		f_setVel(const vec3& l) { m_变换.location = l; }
	virtual void		f_setScl(const vec3& s) { m_变换.scale = s; }




	virtual vec3		f_getLoc() { return m_变换.location; }
	virtual vec3		f_getRot() { return m_变换.rotation; }
	virtual vec3		f_getVel() { return m_变换.rotation; }
	virtual vec3		f_getRotVel() { return { 0,0,0 }; }
	virtual vec3		f_getScl() { return m_变换.scale; }

	virtual void		f_施加力(const vec3& 力) {}
	void f_set绑定物体矩阵(const Mat44f& mat);

};





typedef struct {
	vec4	m_旋转;
	float32	m_长度;
	//S_板载缓存*	m_矩阵;
}S_骨骼;

typedef struct {
	struct S_物体* m_始端;
	struct S_物体* m_末端;
	vec3			m_末端坐标;
	uint32	m_深度;
	uint32	m_迭代次数;
}S_骨骼IK;


typedef struct {
	S_GPU内存块索引 m_骨骼属性;
	S_GPU内存块索引 m_骨骼长度;

	S_GPU内存块索引 m_初始姿态;
	S_GPU内存块索引 m_变换姿态;

	S_GPU内存块索引 m_骨骼变换;
	//S_板载缓存*	m_蒙皮权重;
	//S_板载缓存* m_顶点对应骨骼ID;
	//S_Tranform*	m_变换;
	S_骨骼IK**		m_IK;
	uint32			m_IK数量;

	//uint32			m_ID;
	uint32			m_骨头数量;
}S_骨架;






E_物体类型 f_ob_以名称取类型(std::wstring name);
E_物体类型 f_ob_以名称索引取类型(uint32 index);



